<template>
  <div class="img-test">
    <h2>图片测试页面</h2>
    <div class="upload-container">
      <input type="file" @change="handleImgUpload" accept="image/*" />
      <div class="preview" v-if="imgPreviewUrl">
        <img :src="imgPreviewUrl" alt="图片预览" />
        <div class="download-buttons">
          <button class="download-btn" @click="downloadOriginal">
            <span class="download-icon">↓</span>下载原图
          </button>
          <button class="download-btn" @click="downloadCropped">
            <span class="download-icon">↓</span>下载裁剪图
          </button>
        </div>
      </div>
    </div>
    <router-link to="/" class="back-link">返回首页</router-link>

    <el-dialog
      v-model="showModal"
      title="请选择裁剪区域"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      width="90%"
      @close="closeModal"
    >
      <div class="zoom-controls">
        <button class="zoom-btn" @click="zoomIn">
          <span class="zoom-icon">+</span>放大
        </button>
        <button class="zoom-btn" @click="zoomOut">
          <span class="zoom-icon">-</span>缩小
        </button>
        <button class="zoom-btn" @click="resetCrop">
          <span class="zoom-icon">↺</span>重置
        </button>
      </div>

      <div class="crop-container" ref="cropContainer">
        <img :src="originalImgUrl" ref="cropImage" @load="initCrop" />
      </div>

      <div class="size-buttons">
        <button 
          v-for="size in sizeOptions" 
          :key="size.scale"
          :class="['size-btn', { active: currentScale === size.scale }]"
          @click="changeSize(size.scale)"
        >
          {{ size.label }}
        </button>
      </div>

      <div class="crop-info" v-if="cropInfo">
        原图尺寸: {{ originalSize }}，
        截取尺寸: {{ cropInfo.currentSize }} 
        <span v-if="cropInfo.targetSize">{{ cropInfo.targetSize }}</span>
        <div class="quality-control">
          <el-slider v-model="quality" />
          <span>清晰度: {{ quality }}%</span>
        </div>
      </div>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="closeModal">取消</el-button>
          <el-button type="primary" @click="handleCrop">确认</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import Cropper from 'cropperjs'
import 'cropperjs/dist/cropper.css'

const imgPreviewUrl = ref('')
const originalImgUrl = ref('')
const showModal = ref(false)
const cropImage = ref(null)
const cropper = ref(null)
const cropInfo = ref(null)
const currentScale = ref(1)
const originalSize = ref('')
const quality = ref(50)

const sizeOptions = [
  { scale: 1, label: '1倍(56×70)', width: 56, height: 70 },
  { scale: 1.5, label: '1.5倍 (84×105)', width: 84, height: 105 },
  { scale: 2, label: '2倍 (112×140)', width: 112, height: 140 },
  { scale: 3, label: '3倍 (168×210)', width: 168, height: 210 },
  { scale: 4, label: '4倍 (224×280)', width: 224, height: 280 },
  { scale: 5, label: '5倍 (280×350)', width: 280, height: 350 },
  { scale: 6, label: '6倍 (336×420)', width: 336, height: 420 },
  { scale: 'fit', label: '适应', width: 56, height: 70 }
]

const handleImgUpload = (event) => {
  const file = event.target.files[0]
  if (!file) return

  const reader = new FileReader()
  reader.onload = (e) => {
    const img = new Image()
    img.onload = () => {
      originalSize.value = `${img.width} × ${img.height}`
      originalImgUrl.value = e.target.result
      showCropModal()
    }
    img.src = e.target.result
  }
  reader.readAsDataURL(file)
}

// 计算适应尺寸
const calculateFitSize = (containerData, imageData) => {
  const targetRatio = 56 / 70
  const imageHeight = imageData.naturalHeight
  const imageWidth = imageData.naturalWidth
  
  // 始终使用原图高度，并按比例计算宽度
  const actualHeight = imageHeight
  const actualWidth = Math.round(imageHeight * targetRatio)
  
  // 计算显示比例
  const displayScale = Math.min(
    containerData.width / imageData.naturalWidth,
    containerData.height / imageData.naturalHeight
  )
  
  // 转换为显示尺寸
  const displayWidth = Math.round(actualWidth * displayScale)
  const displayHeight = Math.round(actualHeight * displayScale)

  return { 
    width: displayWidth, 
    height: displayHeight,
    actualWidth,
    actualHeight,
    displayScale
  }
}

// 修改 initCrop 函数
const initCrop = () => {
  const image = cropImage.value
  if (!image) return

  if (cropper.value) {
    cropper.value.destroy()
    cropper.value = null
  }

  cropper.value = new Cropper(image, {
    aspectRatio: 56/70,
    viewMode: 1,
    dragMode: 'move',
    autoCropArea: 1,
    minContainerWidth: 400,
    minContainerHeight: 500,
    background: true,
    modal: true,
    highlight: true,
    zoomOnTouch: true,
    zoomOnWheel: true,
    wheelZoomRatio: 0.1,
    cropBoxMovable: true,
    cropBoxResizable: true,
    toggleDragModeOnDblclick: false,
    ready() {
      // 初始化时使用适应尺寸
      changeSize('fit')
    }
  })
}

// 修改 showCropModal 函数
const showCropModal = () => {
  currentScale.value = 'fit'
  showModal.value = true
}

// 修改 handleCrop 函数
const handleCrop = () => {
  if (!cropper.value) return

  try {
    const size = sizeOptions.find(s => s.scale === currentScale.value)
    if (!size) return

    // 使用预设的固定尺寸进行裁剪
    const targetWidth = currentScale.value === 'fit' ? 
      parseInt(cropInfo.value.currentSize.split('×')[0]) :
      size.width
    const targetHeight = currentScale.value === 'fit' ? 
      parseInt(cropInfo.value.currentSize.split('×')[1]) :
      size.height

    // 创建画布并裁剪
    const canvas = cropper.value.getCroppedCanvas({
      width: targetWidth,
      height: targetHeight,
      imageSmoothingQuality: 'high',
      imageSmoothingEnabled: true
    })

    // 转换为图片
    const finalBase64 = canvas.toDataURL('image/jpeg', Math.max(quality.value / 100, 0.9))
    
    // 更新预览
    imgPreviewUrl.value = finalBase64
    cropInfo.value = {
      ...cropInfo.value,
      fileSize: getBase64Size(finalBase64.split(',')[1])
    }

    // 清理
    if (cropper.value) {
      cropper.value.destroy()
      cropper.value = null
    }
    showModal.value = false
    originalImgUrl.value = ''
  } catch (error) {
    console.error('裁剪失败:', error)
  }
}

// 修改 closeModal 函数
const closeModal = () => {
  // 销毁 cropper
  if (cropper.value) {
    cropper.value.destroy()
    cropper.value = null
  }
  
  // 关闭弹框
  showModal.value = false
}

// 修改 changeSize 函数
const changeSize = (selectedScale) => {
  currentScale.value = selectedScale
  if (!cropper.value) return

  const imageData = cropper.value.getImageData()
  const containerData = cropper.value.getContainerData()

  let targetWidth, targetHeight, outputSize
  if (selectedScale === 'fit') {
    // 适应尺寸：使用原图高度的合适比例
    const maxHeight = Math.min(imageData.naturalHeight, 1000) // 限制最大高度
    targetHeight = maxHeight
    targetWidth = Math.round(targetHeight * (56/70))
  } else {
    outputSize = sizeOptions.find(s => s.scale === selectedScale)
    if (!outputSize) return

    // 固定尺寸：根据原图尺寸计算合适的显示比例
    const baseScale = Math.min(
      imageData.naturalHeight / 1000, // 基于1000像素的高度计算基础比例
      imageData.naturalWidth / 800    // 基于800像素的宽度计算基础比例
    )
    
    // 使用基础比例计算实际尺寸
    targetWidth = Math.round(outputSize.width * baseScale)
    targetHeight = Math.round(outputSize.height * baseScale)

    // 检查是否超出原图尺寸
    if (targetHeight > imageData.naturalHeight) {
      targetHeight = imageData.naturalHeight
      targetWidth = Math.round(targetHeight * (56/70))
    }
  }

  // 计算显示比例
  const displayScale = Math.min(
    containerData.width / imageData.naturalWidth,
    containerData.height / imageData.naturalHeight
  )

  // 计算显示尺寸
  const displayWidth = Math.round(targetWidth * displayScale)
  const displayHeight = Math.round(targetHeight * displayScale)

  // 更新裁剪框
  const cropBoxData = cropper.value.getCropBoxData()
  const centerX = cropBoxData.left + (cropBoxData.width / 2)
  const centerY = cropBoxData.top + (cropBoxData.height / 2)

  // 设置裁剪框位置（保持中心点）
  cropper.value.setCropBoxData({
    left: centerX - (displayWidth / 2),
    top: centerY - (displayHeight / 2),
    width: displayWidth,
    height: displayHeight
  })

  // 更新裁剪信息
  cropInfo.value = {
    currentSize: `${targetWidth} × ${targetHeight}`,
    targetSize: selectedScale === 'fit' ? '适应原图最大尺寸' : 
                `(实际输出尺寸: ${outputSize.width} × ${outputSize.height})`
  }
}

const zoomIn = () => {
  if (cropper.value) {
    cropper.value.zoom(0.1)
  }
}

const zoomOut = () => {
  if (cropper.value) {
    cropper.value.zoom(-0.1)
  }
}

const resetCrop = () => {
  if (cropper.value) {
    cropper.value.reset()
    currentScale.value = 'fit'
  }
}

// 添加文件大小计算函数
const getBase64Size = (base64String) => {
  const padding = base64String.endsWith('==') ? 2 : base64String.endsWith('=') ? 1 : 0
  const base64Length = base64String.length
  const bytes = Math.floor(((base64Length * 0.75) - padding))
  
  if (bytes < 1024) return bytes + ' B'
  else if (bytes < 1048576) return (bytes / 1024).toFixed(2) + ' KB'
  else return (bytes / 1048576).toFixed(2) + ' MB'
}

const downloadImage = (dataUrl, fileName) => {
  const link = document.createElement('a')
  link.href = dataUrl
  link.download = fileName
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

const downloadOriginal = () => {
  if (originalImgUrl.value) {
    downloadImage(originalImgUrl.value, 'original.jpg')
  }
}

const downloadCropped = () => {
  if (imgPreviewUrl.value) {
    downloadImage(imgPreviewUrl.value, `cropped_q${quality.value}.jpg`)
  }
}
</script>

<style scoped>
.img-test {
  padding: 20px;
  text-align: center;
}

.upload-container {
  margin: 20px 0;
}

.preview {
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.preview img {
  max-width: 100%;
  max-height: 500px;
  margin-bottom: 10px;
}

.back-link {
  display: inline-block;
  margin-top: 20px;
  padding: 10px 20px;
  background-color: #666;
  color: white;
  text-decoration: none;
  border-radius: 4px;
}

.back-link:hover {
  background-color: #555;
}

.download-buttons {
  margin-top: 10px;
  display: flex;
  gap: 10px;
}

.download-btn {
  padding: 8px 16px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 5px;
}

.download-btn:hover {
  background-color: #45a049;
}

.download-icon {
  font-weight: bold;
}

.size-buttons {
  margin: 20px 0;
  display: flex;
  justify-content: center;
  gap: 8px;
  flex-wrap: wrap;
  max-width: 800px;
  margin-left: auto;
  margin-right: auto;
}

.size-btn {
  padding: 6px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background-color: white;
  cursor: pointer;
  transition: all 0.3s;
  font-size: 14px;
}

.size-btn:hover {
  background-color: #f0f0f0;
}

.size-btn.active {
  background-color: #4CAF50;
  color: white;
  border-color: #4CAF50;
}

.zoom-controls {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin: 10px 0;
}

.zoom-btn {
  display: flex;
  align-items: center;
  padding: 6px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background-color: white;
  cursor: pointer;
  transition: all 0.3s;
  font-size: 14px;
  min-width: 80px;
  justify-content: center;
}

.zoom-btn:hover {
  background-color: #f0f0f0;
}

.zoom-icon {
  font-weight: bold;
  margin-right: 4px;
  font-size: 16px;
}

.crop-container {
  max-width: 800px;
  max-height: 600px;
  margin: 10px auto;
  overflow: hidden;
  background-color: #f5f5f5;
}

.crop-container img {
  max-width: 100%;
}

.crop-info {
  margin: 10px 0;
  font-size: 14px;
  color: #666;
}

.quality-control {
  margin-top: 10px;
  max-width: 300px;
  margin-left: auto;
  margin-right: auto;
}
</style> 